package xworker.protobuf.netty.handlers.codec.protobuf;

import com.google.protobuf.Message;
import com.google.protobuf.MessageLite;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandler.Sharable;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToMessageEncoder;
import org.xmeta.ActionContext;
import org.xmeta.Thing;
import org.xmeta.util.UtilData;

import java.util.List;

import static io.netty.buffer.Unpooled.wrappedBuffer;

@Sharable
public class SelfProtobufEncoder extends MessageToMessageEncoder<Object> {
	boolean simpleName = false;
	
	public SelfProtobufEncoder(boolean simpleName) {
		this.simpleName = simpleName;
	}
	
    @Override
    protected void encode(ChannelHandlerContext ctx, Object msg, List<Object> out)
            throws Exception {

		byte[] messageBytes = null;
		if(msg instanceof Message){
			Message message = (Message) msg;
			messageBytes = message.toByteArray();
		}else if(msg instanceof MessageLite){
			MessageLite message = (MessageLite) msg;
			messageBytes = message.toByteArray();
		}

		if(messageBytes != null) {
			//动作
			ByteBuf actionBuf = Unpooled.buffer();
			String name = null;
			if (simpleName) {
				name = msg.getClass().getSimpleName();
			} else {
				name = msg.getClass().getName();
			}

			byte[] action = name.getBytes();
			actionBuf.writeByte(action.length);
			actionBuf.writeBytes(action);

			//消息体
			ByteBuf bodyBuf = wrappedBuffer(messageBytes);
			out.add(wrappedBuffer(actionBuf, bodyBuf));
		}else{
			//不编码，传递到下一个编码器
			out.add(msg);
		}
    }
    
    public static SelfProtobufEncoder create(ActionContext actionContext) {
    	Thing self = actionContext.getObject("self");
    	boolean simpleName = UtilData.isTrue(self.doAction("isSimpleName", actionContext));
    	
    	return new SelfProtobufEncoder(simpleName);
    }
}
